home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / utilitys / less_14z / part02 < prev    next >
Internet Message Format  |  1991-07-08  |  61KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i128: Less 1.4Z - text pager, Part02/07
  4. Reply-To: rayz@altair.csustan.edu (R. L. Zarling)
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga.v91i128@ab20.larc.nasa.gov>
  7. References: <comp.sources.amiga.v91i127@ab20.larc.nasa.gov>
  8. Date: 04 Jul 91 17:28:18 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga.misc
  12.  
  13. Submitted-by: rayz@altair.csustan.edu (R. L. Zarling)
  14. Posting-number: Volume 91, Issue 128
  15. Archive-name: utilities/less-1.4z/part02
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 2 (of 7)."
  24. # Contents:  Less1.4Z/ReadMe Less1.4Z/src/ch.c Less1.4Z/src/option.c
  25. #   Less1.4Z/src/output.c Less1.4Z/src/version.c
  26. # Wrapped by tadguy@ab20 on Thu Jul  4 13:28:15 1991
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'Less1.4Z/ReadMe' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'Less1.4Z/ReadMe'\"
  30. else
  31. echo shar: Extracting \"'Less1.4Z/ReadMe'\" \(8241 characters\)
  32. sed "s/^X//" >'Less1.4Z/ReadMe' <<'END_OF_FILE'
  33. XThis is a revision of a port (by Bob Leivian) of version 73 of the "Less"
  34. Xpager from Unix (Fred Fish #149).
  35. X
  36. XLess is an Ascii text pager with the following features:
  37. X
  38. X    -Compatible with WB 1.3 and 2.0 on any Amiga
  39. X    -Handles NTSC, PAL, overscan, etc. screens
  40. X    -Works with pipes (with a consenting shell or pipe: device)
  41. X    -Permits multiple file selection, CLI or Workbench
  42. X    -Forward & backward movement in a variety of ways
  43. X    -Powerful searches, using regular expression patterns
  44. X    -Handles alternative fonts
  45. X    -Handles international Ascii characters
  46. X    -Handles boldface, underline, etc. in ANSI or Unix nroff style
  47. X    -Customizable, using environment or command options
  48. X    -Residentable
  49. X
  50. XLess is still the only pager I know of on the Amiga that handles pipes
  51. Xand multiple file selection.  To me, these two features are essential
  52. Xin a pager.  If your shell supports pipes and expands wildcards (I use
  53. XSteve Koren's outstanding SKsh), you can write things like 'ls | less'
  54. Xor 'less *.readme'.
  55. X
  56. XLess has been around for a long time in the Unix world, and has been
  57. Xported to the Amiga before.  Unfortunately, the earlier Amiga port would
  58. Xnot run on Amiga 3000s and was seriously crippled in the areas of support
  59. Xfor non-NTSC or overscan screens and international characters.
  60. X
  61. XThe current version opens a full-sized window on your workbench screen
  62. X(even PAL or overscan), and displays as much text from the input
  63. Xfiles as it can using the standard system font.  It is smart enough to
  64. Xadjust these values even if you resize the window using the resizing
  65. Xgadget.  It responds to the standard window close gadget, and of course
  66. Xfront/back, drag bar, and 2.0 zoom gadgets.
  67. X
  68. XYou can specify less than a full-sized window from the command line by
  69. Xa new option, -[N,N,N,N].  The four N's are left-edge position, top-edge
  70. Xposition, width, and height in pixels.  Any may be omitted, defaulting
  71. Xto 0.  Zeros in the last two positions mean full width or height.  If
  72. Xnumbers at the end of the list are omitted, their preceding commas may
  73. Xbe omitted also.  If any of the Ns are negative, they are taken to be
  74. Xrelative to the bottom right corner of the screen.  Thus, [-200,-100,
  75. X200,100] would be a 200 by 100 window in the bottom right corner of the
  76. Xscreen, and [0,12,0,-100] would be a full-width window leaving the title
  77. Xbar of the screen and the bottom 100 scan lines exposed.  There is a
  78. Xminimum window size, and if it is violated, or if the window would fall
  79. Xoff the edges of the screen, Less simply forces things to conform.
  80. X
  81. XIt recognizes most ANSI commands to set underlining, italics, boldfacing,
  82. Xor inverse video, in addition to the backspace protocols for boldfacing
  83. Xand underlining that Less has always recognized (if neither of the two
  84. X-u options is set).
  85. X
  86. XThis version of Less is more "Amigatised" in its use of the Amiga keyboard.
  87. XIt allows you to scroll backward in the file by one line using the
  88. Xbackspace key--a sort of logical consequence, IMHO, of the carriage
  89. Xreturn key's use for scrolling forward by single lines.  The arrow keys
  90. X(cursor up, down, left and right) are active:  up and down move you
  91. Xthrough the document by pages; left and right by lines; shifted left
  92. Xand right by half-pages.  The HELP key displays a help message.  I
  93. Xhave added ^N and ^P for next and previous line, ^V for next page, ^S
  94. Xfor forward search, and '<' and '>' for go to top and bottom of file, in
  95. Xresponse to a request from an emacs-type.
  96. X
  97. XWorkbench support is expanded to handle multiple selection of files to
  98. Xbe viewed.  You cannot enter -options from workbench like you can from
  99. XCLI, but Less *does* act upon whatever options are set in the environment
  100. Xvariable LESS.
  101. X
  102. XLess version 1.4Z recognizes the international character set between
  103. Xcharacters 160 and 255 (decimal).
  104. X
  105. XThe regular expression pattern matching in searches has been enabled.
  106. XThese use the powerful Unix 'ed' style patterns.  Any pattern consisting
  107. Xonly of letters, numbers, and spaces will simply search for the given
  108. Xpattern.  But you can use one or more of the metacharacters [].^$()|*+ to
  109. Xengineer very sophisticated searches.  The '.' stands for any single
  110. Xcharacter, and 'x*' stands for 0 or more occurances of x (so 'x.*y'
  111. Xwould match anything that started with x and ended with y).  'x+'
  112. Xworks the same way, for 1 or more occurances of x.  'x?' matches 0 or 1
  113. Xoccurances of x (i.e. 'x' or nothing).  '[abc]' matches any single
  114. Xoccurance of 'a', 'b', or 'c'.  '[^abc]' matches any single character
  115. Xexcept 'a', 'b', or 'c'.  '[a-m]' matches any single character in the
  116. Xrange 'a' through 'm' inclusive.  '^x' finds x only at the beginning of
  117. Xa line; 'x$' only at the end of a line.  'x|y' matches either x or y.  The
  118. Xvarious pieces can be combined, of course, and grouped with parentheses.
  119. X'([Aa]ny|[Ee]ach) +of you' would find any phrase beginning with 'any'
  120. Xor 'each' (possibly capitalized) followed by one or more blanks, followed
  121. Xby 'of you'. ' (can)?not ' matches either 'not' or 'cannot', but not
  122. X'nothing' or 'cancel'.  '[^a-zA-Z]i[^a-zA-Z]' finds all occurances of a
  123. Xvariable 'i' in a program, but does not find 'i' embedded in other
  124. Xvariable names or words.  To match a metacharacter literally, precede it
  125. Xwith a backslash; e.g. '\.  \*' would match a period followed by two
  126. Xspaces and an asterisk.
  127. X
  128. XWith resizeable windows, the number of lines to scroll for page-forward
  129. Xand page-back commands is now recalculated each time the screen is
  130. Xresized.  The -z command now sets the maximum number of lines that will
  131. Xbe scrolled for full-screen movement.  The space bar, for instance, will
  132. Xscroll either -z lines, or a full screen, whichever is less.
  133. X
  134. XHalf-page moves used to be fixed at 10 lines (although alterable
  135. Xby prefixing a u or d command with a different number).  With resizable
  136. Xscreens, this didn't seem to make much sense any more, so I also have
  137. XLess automatically compute the half-page size on startup and resizing of
  138. Xthe window.
  139. X
  140. XMany bugs or unimplemented features have been fixed; they're generally
  141. Xsmall things that casual users will never notice.  The Q and q options
  142. Xwork:  they quiet the visible bell, since there is no audible bell.  The
  143. XE and e options have changed meaning slightly:  You can exit a file upon
  144. Xany attempted forward movement beyond eof (E), or only upon an attempted
  145. Xfull-page movement (e, the default), or you can be barred from exiting
  146. Xvia text movement commands (neither e nor E).  The old business of closing
  147. Xthe window immediately (old E) upon finding eof, before you have time to
  148. Xread the last page of text, was judged useless in the Amiga environment!
  149. XC was made the default for painting screens, for speed.  This version
  150. Xtakes greater pains to assure that the prompt at the bottom of the screen
  151. Xfits in a single line; it is shortened if necessary.  Some bug fixes have
  152. Xmade it harder (I think!) to crash Less (no pun intended).
  153. X
  154. XSignal handling has been improved:  ^C in the Less window will abort
  155. Xsearches, but is otherwise ignored with a warning message.  A BREAK
  156. Xsignal from the launching CLI (^C in the CLI window, if there is one,
  157. Xor AmigaDOS "break" command directed at Less) will immediately
  158. Xterminate the process (with cleanup, of course).  Error handling in
  159. Xconnection with reading the files is much improved, with emphasis on
  160. Xmore informative error messages.
  161. X
  162. XI removed two "features" of the old Amiga port:  Less1.4Z no longer
  163. Xinternally expands wildcarded filenames, and it no longer prints files
  164. Xon the system printer.  I think both of these functions are better done
  165. Xby other means; e.g. SKsh or some other shell for wildcard expansion,
  166. Xand copying to prt: or using one of the many printer utilities to get
  167. Xprintouts.  Less is a good pager; it doesn't need to be bogged down and
  168. Xfattened up with random other capability.  In any event, since I didn't
  169. Xneed or want these functions, it seemed a lot easier to remove them
  170. Xthan to rewrite them.
  171. X
  172. XThe "clean data" option of the original Unix no longer makes sense in
  173. Xthis version, and has been deleted.
  174. X
  175. XLess1.4Z was compiled with SAS-C (formerly Lattice) v5.10a, using the
  176. Xversion 2.0 include files.
  177. X
  178. X--------------------------------------------------------------
  179. X
  180. XRay Zarling
  181. XCalifornia State Univ. Stanislaus
  182. XTurlock, CA 95380
  183. X
  184. Xrayz@csustan.edu
  185. END_OF_FILE
  186. if test 8241 -ne `wc -c <'Less1.4Z/ReadMe'`; then
  187.     echo shar: \"'Less1.4Z/ReadMe'\" unpacked with wrong size!
  188. fi
  189. # end of 'Less1.4Z/ReadMe'
  190. fi
  191. if test -f 'Less1.4Z/src/ch.c' -a "${1}" != "-c" ; then 
  192.   echo shar: Will not clobber existing file \"'Less1.4Z/src/ch.c'\"
  193. else
  194. echo shar: Extracting \"'Less1.4Z/src/ch.c'\" \(12784 characters\)
  195. sed "s/^X//" >'Less1.4Z/src/ch.c' <<'END_OF_FILE'
  196. X/*
  197. X * Low level character input from the input file.
  198. X * We use these special purpose routines which optimize moving
  199. X * both forward and backward from the current read pointer.
  200. X */
  201. X
  202. X#ifdef AMIGA
  203. X/* Compile with -HPreHeader.q to get "less.h"! */
  204. X#else
  205. X#include "less.h"
  206. X#endif
  207. X
  208. X
  209. X/* Prototypes for functions defined in ch.c */
  210. X
  211. Xstatic int fch_get __PROTO((void));
  212. Xstatic int buffered __PROTO((long block));
  213. X
  214. X
  215. Xpublic int file = -1;   /* File descriptor of the input file */
  216. X
  217. X/*
  218. X * Pool of buffers holding the most recently used blocks of the input file.
  219. X */
  220. X#define BUFSIZ  1024
  221. Xstruct buf {
  222. X        struct buf *next, *prev;
  223. X        long block;
  224. X        char data[BUFSIZ];
  225. X};
  226. Xstatic struct buf *bufs = NULL;
  227. Xpublic int nbufs;
  228. X
  229. X/*
  230. X * The buffer pool is kept as a doubly-linked circular list,
  231. X * in order from most- to least-recently used.
  232. X * The circular list is anchored by buf_anchor.
  233. X */
  234. Xstatic struct {
  235. X        struct buf *next, *prev;
  236. X} buf_anchor;
  237. X#define END_OF_CHAIN    ((struct buf *)&buf_anchor)
  238. X#define buf_head        buf_anchor.next
  239. X#define buf_tail        buf_anchor.prev
  240. X
  241. X/*
  242. X * If we fail to allocate enough memory for buffers, we try to limp
  243. X * along with a minimum number of buffers.
  244. X */
  245. X#define DEF_NBUFS       2       /* Minimum number of buffers */
  246. X
  247. X#ifndef AMIGA
  248. Xextern int clean_data;
  249. X#endif
  250. Xextern int ispipe;
  251. Xextern int sigs;
  252. X
  253. X#if LOGFILE
  254. Xextern int logfile;
  255. X#endif
  256. X
  257. X/*
  258. X * Current position in file.
  259. X * Stored as a block number and an offset into the block.
  260. X */
  261. Xstatic long ch_block;
  262. Xstatic int ch_offset;
  263. X
  264. X/*
  265. X * Length of file, needed if input is a pipe.
  266. X */
  267. Xstatic POSITION ch_fsize;
  268. X
  269. X/*
  270. X * Largest block number read if input is standard input (a pipe).
  271. X */
  272. Xstatic long last_piped_block;
  273. X
  274. X/*
  275. X * Get the character pointed to by the read pointer.
  276. X * ch_get() is a macro which is more efficient to call
  277. X * than fch_get (the function), in the usual case
  278. X * that the block desired is at the head of the chain.
  279. X */
  280. X#define ch_get()   ((buf_head->block == ch_block) ? \
  281. X                        buf_head->data[ch_offset] : fch_get())
  282. X
  283. X#ifdef __STDC__
  284. Xstatic int fch_get (void)
  285. X#else
  286. X        static int
  287. Xfch_get()
  288. X#endif
  289. X{
  290. X        register struct buf *bp;
  291. X        register int n;
  292. X        register int end;
  293. X        POSITION pos;
  294. X
  295. X        /*
  296. X         * Look for a buffer holding the desired block.
  297. X         */
  298. X        for (bp = buf_head;  bp != END_OF_CHAIN;  bp = bp->next)
  299. X                if (bp->block == ch_block)
  300. X                        goto found;
  301. X        /*
  302. X         * Block is not in a buffer.
  303. X         * Take the least recently used buffer
  304. X         * and read the desired block into it.
  305. X         */
  306. X        bp = buf_tail;
  307. X        bp->block = ch_block;
  308. X        pos = ch_block * BUFSIZ;
  309. X        if (ispipe)
  310. X        {
  311. X                /*
  312. X                 * The block requested should be one more than
  313. X                 * the last block read.
  314. X                 */
  315. X                if (ch_block != ++last_piped_block)
  316. X                {
  317. X                        /* This "should not happen". */
  318. X                        char message[80];
  319. X                        sprintf(message, "Pipe error: last %ld, want %ld\n",
  320. X                                (long)last_piped_block-1, (long)ch_block);
  321. X                        error(message);
  322. X                        quit();
  323. X                }
  324. X        } else
  325. X                lseek(file, pos, 0);
  326. X
  327. X        /*
  328. X         * Read the block.  This may take several reads if the input
  329. X         * is coming from standard input, due to the nature of pipes.
  330. X         */
  331. X        end = 0;
  332. X        while ((n = read(file, &bp->data[end], BUFSIZ-end)) > 0)
  333. X                if ((end += n) >= BUFSIZ)
  334. X                        break;
  335. X
  336. X        if (n < 0)
  337. X        {
  338. X                error("read error");
  339. X                quit();
  340. X        }
  341. X
  342. X#if LOGFILE
  343. X        /*
  344. X         * If we have a log file, write this block to it.
  345. X         */
  346. X        if (logfile >= 0 && end > 0)
  347. X                write(logfile, bp->data, end);
  348. X#endif
  349. X
  350. X        /*
  351. X         * Set an EOF marker in the buffered data itself.
  352. X         * Then ensure the data is "clean": there are no
  353. X         * extra EOF chars in the data and that the "meta"
  354. X         * bit (the 0200 bit) is reset in each char.
  355. X         */
  356. X        if (end < BUFSIZ)
  357. X        {
  358. X                ch_fsize = pos + end;
  359. X                bp->data[end] = EOF;
  360. X        }
  361. X
  362. X#ifndef AMIGA
  363. X        if (!clean_data)
  364. X#endif
  365. X                while (--end >= 0)
  366. X                {
  367. X#ifdef EIGHTBIT
  368. X                        /* We handle all 8-bit characters, except these,
  369. X                           which are flags for special printing
  370. X                         */
  371. X                        switch ( bp->data[end] )
  372. X                        {
  373. X                        case UL_CHAR:
  374. X                        case UE_CHAR:
  375. X                        case BO_CHAR:
  376. X                        case BE_CHAR:
  377. X                        case IT_CHAR:
  378. X                        case IE_CHAR:
  379. X                        case NV_CHAR:
  380. X                        case NE_CHAR:
  381. X                                bp->data[end] = '\177';
  382. X                        default:
  383. X                                break;
  384. X                        }
  385. X#else
  386. X#ifdef ANSIGR
  387. X                        if ( (unsigned char)(bp->data[end]) != 0x9b )
  388. X#endif
  389. X                        bp->data[end] &= 0177;
  390. X#endif
  391. X                        if (bp->data[end] == EOF)
  392. X                                bp->data[end] = '@';
  393. X                }
  394. X
  395. X    found:
  396. X        /* if (buf_head != bp) {this is guaranteed by the ch_get macro} */
  397. X        {
  398. X                /*
  399. X                 * Move the buffer to the head of the buffer chain.
  400. X                 * This orders the buffer chain, most- to least-recently used.
  401. X                 */
  402. X                bp->next->prev = bp->prev;
  403. X                bp->prev->next = bp->next;
  404. X
  405. X                bp->next = buf_head;
  406. X                bp->prev = END_OF_CHAIN;
  407. X                buf_head->prev = bp;
  408. X                buf_head = bp;
  409. X        }
  410. X        return (int)(bp->data[ch_offset]);
  411. X}
  412. X
  413. X#if LOGFILE
  414. X/*
  415. X * Close the logfile.
  416. X * If we haven't read all of standard input into it, do that now.
  417. X */
  418. X        public void
  419. Xend_logfile()
  420. X{
  421. X        static int tried;
  422. X
  423. X        if (logfile < 0)
  424. X                return;
  425. X        if (!tried && ch_fsize == NULL_POSITION)
  426. X        {
  427. X                tried = 1;
  428. X                lower_left();
  429. X                clear_eol();
  430. X                so_enter();
  431. X                putstr("finishing logfile... (interrupt to abort)");
  432. X                so_exit();
  433. X                flush();
  434. X                while (sigs == 0 && ch_forw_get() != EOF)
  435. X                        ;
  436. X        }
  437. X        close(logfile);
  438. X        logfile = -1;
  439. X}
  440. X#endif
  441. X
  442. X/*
  443. X * Determine if a specific block is currently in one of the buffers.
  444. X */
  445. X#ifdef __STDC__
  446. Xstatic int buffered (long block)
  447. X#else
  448. X        static int
  449. Xbuffered(block)
  450. X        long block;
  451. X#endif
  452. X{
  453. X        register struct buf *bp;
  454. X
  455. X        for (bp = buf_head;  bp != END_OF_CHAIN;  bp = bp->next)
  456. X                if (bp->block == block)
  457. X                        return (1);
  458. X        return (0);
  459. X}
  460. X
  461. X/*
  462. X * Seek to a specified position in the file.
  463. X * Return 0 if successful, non-zero if can't seek there.
  464. X */
  465. X#ifdef __STDC__
  466. Xint ch_seek (register POSITION pos)
  467. X#else
  468. X        public int
  469. Xch_seek(pos)
  470. X        register POSITION pos;
  471. X#endif
  472. X{
  473. X        long new_block;
  474. X
  475. X        new_block = pos / BUFSIZ;
  476. X        if (!ispipe || new_block == last_piped_block + 1 || buffered(new_block))
  477. X        {
  478. X                /*
  479. X                 * Set read pointer.
  480. X                 */
  481. X                ch_block = new_block;
  482. X                ch_offset = pos % BUFSIZ;
  483. X                return (0);
  484. X        }
  485. X        return (1);
  486. X}
  487. X
  488. X/*
  489. X * Seek to the end of the file.
  490. X */
  491. X#ifdef __STDC__
  492. Xint ch_end_seek (void)
  493. X#else
  494. X        public int
  495. Xch_end_seek()
  496. X#endif
  497. X{
  498. X        if (ispipe)
  499. X        {
  500. X                /*
  501. X                 * Do it the slow way: read till end of data.
  502. X                 */
  503. X                while (ch_forw_get() != EOF)
  504. X                        ;
  505. X        } else
  506. X        {
  507. X                (void) ch_seek((POSITION)(lseek(file, (offset_t)0, 2)));
  508. X        }
  509. X        return (0);
  510. X}
  511. X
  512. X/*
  513. X * Seek to the beginning of the file, or as close to it as we can get.
  514. X * We may not be able to seek there if input is a pipe and the
  515. X * beginning of the pipe is no longer buffered.
  516. X */
  517. X#ifdef __STDC__
  518. Xint ch_beg_seek (void)
  519. X#else
  520. X        public int
  521. Xch_beg_seek()
  522. X#endif
  523. X{
  524. X        register struct buf *bp, *firstbp;
  525. X
  526. X        /*
  527. X         * Try a plain ch_seek first.
  528. X         */
  529. X        if (ch_seek((POSITION)0) == 0)
  530. X                return (0);
  531. X
  532. X        /*
  533. X         * Can't get to position 0.
  534. X         * Look thru the buffers for the one closest to position 0.
  535. X         */
  536. X        firstbp = bp = buf_head;
  537. X        if (bp == END_OF_CHAIN)
  538. X                return (1);
  539. X        while ((bp = bp->next) != END_OF_CHAIN)
  540. X                if (bp->block < firstbp->block)
  541. X                        firstbp = bp;
  542. X        ch_block = firstbp->block;
  543. X        ch_offset = 0;
  544. X        return (0);
  545. X}
  546. X
  547. X/*
  548. X * Return the length of the file, if known.
  549. X */
  550. X#ifdef __STDC__
  551. XPOSITION ch_length (void)
  552. X#else
  553. X        public POSITION
  554. Xch_length()
  555. X#endif
  556. X{
  557. X        if (ispipe)
  558. X                return (ch_fsize);
  559. X        return ((POSITION)(lseek(file, (offset_t)0, 2)));
  560. X}
  561. X
  562. X/*
  563. X * Return the current position in the file.
  564. X */
  565. X#ifdef __STDC__
  566. XPOSITION ch_tell (void)
  567. X#else
  568. X        public POSITION
  569. Xch_tell()
  570. X#endif
  571. X{
  572. X        return (ch_block * BUFSIZ + ch_offset);
  573. X}
  574. X
  575. X/*
  576. X * Get the current char and post-increment the read pointer.
  577. X */
  578. X#ifdef __STDC__
  579. Xint ch_forw_get (void)
  580. X#else
  581. X        public int
  582. Xch_forw_get()
  583. X#endif
  584. X{
  585. X        register int c;
  586. X
  587. X        c = ch_get();
  588. X        if (c != EOF && ++ch_offset >= BUFSIZ)
  589. X        {
  590. X                ch_offset = 0;
  591. X                ch_block ++;
  592. X        }
  593. X        return (c);
  594. X}
  595. X
  596. X/*
  597. X * Pre-decrement the read pointer and get the new current char.
  598. X */
  599. X#ifdef __STDC__
  600. Xint ch_back_get (void)
  601. X#else
  602. X        public int
  603. Xch_back_get()
  604. X#endif
  605. X{
  606. X        register int c;
  607. X
  608. X        if (--ch_offset < 0)
  609. X        {
  610. X                if (ch_block <= 0 || (ispipe && !buffered(ch_block-1)))
  611. X                {
  612. X                        ch_offset = 0;
  613. X                        return (EOF);
  614. X                }
  615. X                ch_offset = BUFSIZ - 1;
  616. X                ch_block--;
  617. X        }
  618. X        c = ch_get();
  619. X        return (c);
  620. X}
  621. X
  622. X/*
  623. X * Initialize the buffer pool to all empty.
  624. X * Caller suggests that we use want_nbufs buffers.
  625. X */
  626. X#ifdef __STDC__
  627. Xvoid ch_init (int want_nbufs)
  628. X#else
  629. X        public void
  630. Xch_init(want_nbufs)
  631. X        int want_nbufs;
  632. X#endif
  633. X{
  634. X        register struct buf *bp;
  635. X#ifndef AMIGA
  636. X        char *calloc();
  637. X#endif
  638. X
  639. X        if (nbufs < want_nbufs)
  640. X        {
  641. X                /*
  642. X                 * We don't have enough buffers.
  643. X                 * Free what we have (if any) and allocate some new ones.
  644. X                 */
  645. X                if (bufs != NULL)
  646. X                        free((char *)bufs);
  647. X                bufs = (struct buf *) calloc(want_nbufs, sizeof(struct buf));
  648. X                nbufs = want_nbufs;
  649. X                if (bufs == NULL)
  650. X                {
  651. X                        /*
  652. X                         * Couldn't get that many.
  653. X                         * Try for a small default number of buffers.
  654. X                         */
  655. X                        char message[80];
  656. X                        sprintf(message,
  657. X                          "Cannot allocate %d buffers.  Using %d buffers.",
  658. X                          nbufs, DEF_NBUFS);
  659. X                        error(message);
  660. X                        bufs = (struct buf *) calloc(DEF_NBUFS, sizeof(struct buf));
  661. X                        nbufs = DEF_NBUFS;
  662. X                        if (bufs == NULL)
  663. X                        {
  664. X                                /*
  665. X                                 * Couldn't even get the smaller number of bufs.
  666. X                                 * Something is wrong here, don't continue.
  667. X                                 */
  668. X                                sprintf(message,
  669. X                                "Cannot even allocate %d buffers!  Quitting.",
  670. X                                  DEF_NBUFS);
  671. X                                error(message);
  672. X                                quit();
  673. X                                /*NOTREACHED*/
  674. X                        }
  675. X                }
  676. X        }
  677. X
  678. X        /*
  679. X         * Initialize the buffers to empty.
  680. X         * Set up the circular list.
  681. X         */
  682. X        for (bp = &bufs[0];  bp < &bufs[nbufs];  bp++)
  683. X        {
  684. X                bp->next = bp + 1;
  685. X                bp->prev = bp - 1;
  686. X                bp->block = (long)(-1);
  687. X        }
  688. X        bufs[0].prev = bufs[nbufs-1].next = END_OF_CHAIN;
  689. X        buf_head = &bufs[0];
  690. X        buf_tail = &bufs[nbufs-1];
  691. X        last_piped_block = -1;
  692. X        ch_fsize = NULL_POSITION;
  693. X        (void) ch_seek((POSITION)0);
  694. X}
  695. END_OF_FILE
  696. if test 12784 -ne `wc -c <'Less1.4Z/src/ch.c'`; then
  697.     echo shar: \"'Less1.4Z/src/ch.c'\" unpacked with wrong size!
  698. fi
  699. # end of 'Less1.4Z/src/ch.c'
  700. fi
  701. if test -f 'Less1.4Z/src/option.c' -a "${1}" != "-c" ; then 
  702.   echo shar: Will not clobber existing file \"'Less1.4Z/src/option.c'\"
  703. else
  704. echo shar: Extracting \"'Less1.4Z/src/option.c'\" \(16082 characters\)
  705. sed "s/^X//" >'Less1.4Z/src/option.c' <<'END_OF_FILE'
  706. X/*
  707. X * Process command line options.
  708. X * Each option is a single letter which controls a program variable.
  709. X * The options have defaults which may be changed via
  710. X * the command line option, or toggled via the "-" command.
  711. X */
  712. X
  713. X#ifdef AMIGA
  714. X/* Compile with -HPreHeader.q to get "less.h"! */
  715. X#else
  716. X#include "less.h"
  717. X#endif
  718. X
  719. X
  720. X#ifdef AMIGA
  721. X/* use the old-style toupper() that doesn't check its arguement */
  722. X#undef toupper
  723. X#define toupper(c)      ((c)-'a'+'A')
  724. X#endif
  725. X
  726. X#define END_OPTION_STRING       ('$')
  727. X
  728. X/*
  729. X * Types of options.
  730. X */
  731. X#define BOOL            01      /* Boolean option: 0 or 1 */
  732. X#define TRIPLE          02      /* Triple-valued option: 0, 1 or 2 */
  733. X#define NUMBER          04      /* Numeric option */
  734. X#define REPAINT         040     /* Repaint screen after toggling option */
  735. X#define NO_TOGGLE       0100    /* Option cannot be toggled with "-" cmd */
  736. X
  737. X/* Prototypes for functions defined in option.c */
  738. X
  739. Xstatic char *optstring __PROTO((char *s));
  740. Xstatic int getnum __PROTO((char **sp, int c));
  741. X
  742. X
  743. X/*
  744. X * Variables controlled by command line options.
  745. X */
  746. Xpublic int p_nbufs, f_nbufs;    /* Number of buffers.  There are two values,
  747. X                                   one used for input from a pipe and
  748. X                                   the other for input from a file. */
  749. X#ifndef AMIGA
  750. Xpublic int clean_data;          /* Can we assume the data is "clean"?
  751. X                                   (That is, free of nulls, etc) */
  752. X#endif
  753. Xpublic int quiet;               /* Should we suppress the audible bell? */
  754. Xpublic int top_search;          /* Should forward searches start at the top
  755. X                                   of the screen? (alternative is bottom) */
  756. Xpublic int top_scroll;          /* Repaint screen from top?
  757. X                                   (alternative is scroll from bottom) */
  758. Xpublic int pr_type;             /* Type of prompt (short, medium, long) */
  759. Xpublic int bs_mode;             /* How to process backspaces */
  760. X#ifdef DUMBTERM
  761. Xpublic int know_dumb;           /* Don't complain about dumb terminals */
  762. X#endif
  763. Xpublic int quit_at_eof;         /* Quit after hitting end of file twice */
  764. Xpublic int squeeze;             /* Squeeze multiple blank lines into one */
  765. Xpublic int tabstop;             /* Tab settings */
  766. Xpublic int back_scroll;         /* Repaint screen on backwards movement */
  767. Xpublic int twiddle;             /* Display "~" for lines after EOF */
  768. X
  769. Xextern char *prproto[];
  770. Xextern int nbufs;
  771. Xextern int sc_window;
  772. X#ifdef AMIGA
  773. Xpublic int scroll;
  774. Xpublic int sc_window_spec;      /* user's requested -z */
  775. Xextern int Wind_Spec[4];        /* User-specified window size/position */
  776. X#endif
  777. Xextern char *first_cmd;
  778. Xextern char *every_first_cmd;
  779. X#if LOGFILE
  780. Xextern char *namelogfile;
  781. Xextern int force_logfile;
  782. X#endif
  783. X
  784. X#define DEF_F_NBUFS     5       /* Default for f_nbufs */
  785. X#define DEF_P_NBUFS     12      /* Default for p_nbufs */
  786. X
  787. Xstatic struct option
  788. X{
  789. X        char oletter;           /* The controlling letter (a-z) */
  790. X        char otype;             /* Type of the option */
  791. X        int odefault;           /* Default value */
  792. X        int *ovar;              /* Pointer to the associated variable */
  793. X        char *odesc[3];         /* Description of each value */
  794. X} option[] =
  795. X{
  796. X        { 'c', TRIPLE, 2, &top_scroll,
  797. X                { "Repaint by scrolling from bottom of screen",
  798. X                  "Repaint by clearing each line",
  799. X                  "Repaint by painting from top of screen"
  800. X                }
  801. X        },
  802. X#ifdef DUMBTERM
  803. X        { 'd', BOOL|NO_TOGGLE, 0, &know_dumb,
  804. X                { NULL, NULL, NULL}
  805. X        },
  806. X#endif
  807. X        { 'e', TRIPLE, 1, &quit_at_eof,
  808. X                { "Don't quit at end-of-file",
  809. X#ifdef AMIGA
  810. X                  "Space bar quits at end-of-file",
  811. X                  "Quit at end-of-file"
  812. X#else
  813. X                  "Quit at end-of-file",
  814. X                  "Quit immediately at end-of-file"
  815. X#endif
  816. X                }
  817. X        },
  818. X#ifndef AMIGA
  819. X        { 'f', BOOL, 0, &clean_data,
  820. X                { "Don't assume data is clean",
  821. X                  "Assume data is clean",
  822. X                  NULL
  823. X                }
  824. X        },
  825. X#endif
  826. X        { 'h', NUMBER, -1, &back_scroll, /* default set at window open */
  827. X                { "Backwards scroll limit is %d lines",
  828. X                  NULL, NULL
  829. X                }
  830. X        },
  831. X        { 'm', TRIPLE, 1, &pr_type,
  832. X                { "Short prompt",
  833. X                  "Medium prompt",
  834. X                  "Long prompt"
  835. X                }
  836. X        },
  837. X        { 'q', TRIPLE, 0, &quiet,
  838. X                { "Ring the bell for errors AND at eof/bof",
  839. X                  "Ring the bell for errors but not at eof/bof",
  840. X                  "Never ring the bell"
  841. X                }
  842. X        },
  843. X        { 's', BOOL|REPAINT, 0, &squeeze,
  844. X                { "Don't squeeze multiple blank lines",
  845. X                  "Squeeze multiple blank lines",
  846. X                  NULL
  847. X                }
  848. X        },
  849. X        { 't', BOOL, 1, &top_search,
  850. X                { "Forward search starts from bottom of screen",
  851. X                  "Forward search starts from top of screen",
  852. X                  NULL
  853. X                }
  854. X        },
  855. X        { 'u', TRIPLE|REPAINT, 0, &bs_mode,
  856. X
  857. X                { "Underlined text displayed in underline mode",
  858. X                  "Backspaces cause overstrike",
  859. X                  "Backspaces print as ^H"
  860. X                }
  861. X        },
  862. X        { 'w', BOOL|REPAINT, 1, &twiddle,
  863. X                { "Display nothing for lines after end-of-file",
  864. X                  "Display ~ for lines after end-of-file",
  865. X                  NULL
  866. X                }
  867. X        },
  868. X        { 'x', NUMBER|REPAINT, 8, &tabstop,
  869. X                { "Tab stops every %d spaces",
  870. X                  NULL, NULL
  871. X                }
  872. X        },
  873. X        { 'z', NUMBER|REPAINT, -1, &sc_window,
  874. X                { "Scroll window size is %d lines",
  875. X                  NULL, NULL
  876. X                }
  877. X        },
  878. X        { '\0' }
  879. X};
  880. X
  881. Xpublic char all_options[64];    /* List of all valid options */
  882. X
  883. X/*
  884. X * Initialize each option to its default value.
  885. X */
  886. X#ifdef __STDC__
  887. Xvoid init_option (void)
  888. X#else
  889. X        public void
  890. Xinit_option()
  891. X#endif
  892. X{
  893. X        register struct option *o;
  894. X        register char *p;
  895. X
  896. X        /*
  897. X         * First do special cases, not in option table.
  898. X         */
  899. X        first_cmd = every_first_cmd = NULL;
  900. X        f_nbufs = DEF_F_NBUFS;          /* -bf */
  901. X        p_nbufs = DEF_P_NBUFS;          /* -bp */
  902. X
  903. X        p = all_options;
  904. X        *p++ = 'b';
  905. X
  906. X        for (o = option;  o->oletter != '\0';  o++)
  907. X        {
  908. X                /*
  909. X                 * Set each variable to its default.
  910. X                 * Also make a list of all options, in "all_options".
  911. X                 */
  912. X                *(o->ovar) = o->odefault;
  913. X                *p++ = o->oletter;
  914. X                if (o->otype & TRIPLE)
  915. X                        *p++ = toupper(o->oletter);
  916. X        }
  917. X        *p = '\0';
  918. X}
  919. X
  920. X/*
  921. X * Toggle command line flags from within the program.
  922. X * Used by the "-" command.
  923. X */
  924. X#ifdef __STDC__
  925. Xvoid toggle_option (char *s)
  926. X#else
  927. X        public void
  928. Xtoggle_option(s)
  929. X        char *s;
  930. X#endif
  931. X{
  932. X        int c;
  933. X        register struct option *o;
  934. X        char *msg;
  935. X        int n;
  936. X        int dorepaint;
  937. X        char message[100];
  938. X        char buf[5];
  939. X
  940. X        c = *s++;
  941. X
  942. X        /*
  943. X         * First check for special cases not handled by the option table.
  944. X         */
  945. X        switch (c)
  946. X        {
  947. X        case 'b':
  948. X                sprintf(message, "%d buffers", nbufs);
  949. X                error(message);
  950. X                return;
  951. X        }
  952. X
  953. X        msg = NULL;
  954. X        for (o = option;  o->oletter != '\0';  o++)
  955. X        {
  956. X                if (o->otype & NO_TOGGLE)
  957. X                        continue;
  958. X                dorepaint = (o->otype & REPAINT);
  959. X                if ((o->otype & BOOL) && (o->oletter == c))
  960. X                {
  961. X                        /*
  962. X                         * Boolean option:
  963. X                         * just toggle it.
  964. X                         */
  965. X                        *(o->ovar) = ! *(o->ovar);
  966. X                } else if ((o->otype & TRIPLE) && (o->oletter == c))
  967. X                {
  968. X                        /*
  969. X                         * Triple-valued option with lower case letter:
  970. X                         * make it 1 unless already 1, then make it 0.
  971. X                         */
  972. X                        *(o->ovar) = (*(o->ovar) == 1) ? 0 : 1;
  973. X                } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
  974. X                {
  975. X                        /*
  976. X                         * Triple-valued option with upper case letter:
  977. X                         * make it 2 unless already 2, then make it 0.
  978. X                         */
  979. X                        *(o->ovar) = (*(o->ovar) == 2) ? 0 : 2;
  980. X                } else if ((o->otype & NUMBER) && (o->oletter == c))
  981. X                {
  982. X                        n = getnum(&s, '\0');
  983. X                        if (n < 0)
  984. X                        {
  985. X                                /*
  986. X                                 * No number; just a query.
  987. X                                 * No need to repaint screen.
  988. X                                 */
  989. X                                dorepaint = 0;
  990. X                        } else
  991. X                        {
  992. X                                /*
  993. X                                 * Number follows the option letter.
  994. X                                 * Set the variable to that number.
  995. X                                 */
  996. X                                *(o->ovar) = n;
  997. X#ifdef AMIGA
  998. X                                if ( c == 'z' )
  999. X                                {
  1000. X                                        sc_window_spec = sc_window;
  1001. X                                        set_scroll();
  1002. X                                }
  1003. X#endif
  1004. X                        }
  1005. X                        sprintf(message, o->odesc[0],
  1006. X                                (o->ovar == &back_scroll) ?
  1007. X                                get_back_scroll() : *(o->ovar));
  1008. X                        msg = message;
  1009. X                } else
  1010. X                        continue;
  1011. X
  1012. X
  1013. X                if (dorepaint)
  1014. X                        repaint();
  1015. X                if (msg == NULL)
  1016. X                        msg = o->odesc[*(o->ovar)];
  1017. X                error(msg);
  1018. X                return;
  1019. X        }
  1020. X
  1021. X        if (control_char(c))
  1022. X                sprintf(buf, "^%c", carat_char(c));
  1023. X        else
  1024. X                sprintf(buf, "%c", c);
  1025. X        sprintf(message, "\"-%s\": no such flag.  Use one of \"%s\"",
  1026. X                buf, all_options);
  1027. X        error(message);
  1028. X}
  1029. X
  1030. X/*
  1031. X * Scan to end of string or to an END_OPTION_STRING character.
  1032. X * In the latter case, replace the char with a null char.
  1033. X * Return a pointer to the remainder of the string, if any.
  1034. X */
  1035. X#ifdef __STDC__
  1036. Xstatic char *optstring (char *s)
  1037. X#else
  1038. X        static char *
  1039. Xoptstring(s)
  1040. X        char *s;
  1041. X#endif
  1042. X{
  1043. X        register char *p;
  1044. X
  1045. X        for (p = s;  *p != '\0';  p++)
  1046. X                if (*p == END_OPTION_STRING)
  1047. X                {
  1048. X                        *p = '\0';
  1049. X                        return (p+1);
  1050. X                }
  1051. X        return (p);
  1052. X}
  1053. X
  1054. X/*
  1055. X * Scan an argument (either from command line or from LESS environment
  1056. X * variable) and process it.
  1057. X */
  1058. X#ifdef __STDC__
  1059. Xvoid scan_option (char *s)
  1060. X#else
  1061. X        public void
  1062. Xscan_option(s)
  1063. X        char *s;
  1064. X#endif
  1065. X{
  1066. X        register struct option *o;
  1067. X        register int c;
  1068. X        char message[80];
  1069. X
  1070. X        if (s == NULL)
  1071. X                return;
  1072. X
  1073. X    next:
  1074. X        if (*s == '\0')
  1075. X        {
  1076. X                sc_window_spec = sc_window;
  1077. X                return;
  1078. X        }
  1079. X        switch (c = *s++)
  1080. X        {
  1081. X        case '-':
  1082. X        case ' ':
  1083. X        case '\t':
  1084. X        case END_OPTION_STRING:
  1085. X                goto next;
  1086. X        case '+':
  1087. X                if (*s == '+')
  1088. X                        every_first_cmd = ++s;
  1089. X                first_cmd = s;
  1090. X                s = optstring(s);
  1091. X                goto next;
  1092. X        case 'P':
  1093. X                switch (*s)
  1094. X                {
  1095. X                case 'm':  prproto[PR_MEDIUM] = ++s;  break;
  1096. X                case 'M':  prproto[PR_LONG] = ++s;    break;
  1097. X                default:   prproto[PR_SHORT] = s;     break;
  1098. X                }
  1099. X                s = optstring(s);
  1100. X                goto next;
  1101. X#if LOGFILE
  1102. X        case 'L':
  1103. X                force_logfile = 1;
  1104. X                /* fall thru */
  1105. X        case 'l':
  1106. X                namelogfile = s;
  1107. X                s = optstring(s);
  1108. X                goto next;
  1109. X#endif
  1110. X        case 'b':
  1111. X                switch (*s)
  1112. X                {
  1113. X                case 'f':
  1114. X                        s++;
  1115. X                        f_nbufs = getnum(&s, 'b');
  1116. X                        break;
  1117. X                case 'p':
  1118. X                        s++;
  1119. X                        p_nbufs = getnum(&s, 'b');
  1120. X                        break;
  1121. X                default:
  1122. X                        f_nbufs = p_nbufs = getnum(&s, 'b');
  1123. X                        break;
  1124. X                }
  1125. X                goto next;
  1126. X        case '0':  case '1':  case '2':  case '3':  case '4':
  1127. X        case '5':  case '6':  case '7':  case '8':  case '9':
  1128. X                {
  1129. X                        /*
  1130. X                         * Handle special "more" compatibility form "-number"
  1131. X                         * to set the scrolling window size.
  1132. X                         */
  1133. X                        s--;
  1134. X                        sc_window = getnum(&s, '-');
  1135. X                        goto next;
  1136. X                }
  1137. X#ifdef AMIGA
  1138. X        case '[':   /* window specifier */
  1139. X                {
  1140. X                        int i, rel;
  1141. X
  1142. X                        for (i = 0; i < 4; i++)
  1143. X                        {
  1144. X                            rel = 1;
  1145. X                            while ( *s == ' ' ) s++;
  1146. X                            if ( *s == ',' )
  1147. X                                { s++; continue; }
  1148. X                            if ( *s == '-' )
  1149. X                                { s++; rel = -1; }
  1150. X                            if ( *s == ']' || *s == '\0' ) break;
  1151. X                            Wind_Spec[i] = rel * getnum ( &s, s[-1] );
  1152. X                            if ( *s == ',' ) s++;
  1153. X                        }
  1154. X                        if ( *s++ != ']' )
  1155. X                        {
  1156. X                            error ("Invalid window specification");
  1157. X                            quit();
  1158. X                        }
  1159. X                        goto next;
  1160. X                }
  1161. X#endif
  1162. X        }
  1163. X
  1164. X        for (o = option;  o->oletter != '\0';  o++)
  1165. X        {
  1166. X                if ((o->otype & BOOL) && (o->oletter == c))
  1167. X                {
  1168. X                        *(o->ovar) = ! o->odefault;
  1169. X                        goto next;
  1170. X                } else if ((o->otype & TRIPLE) && (o->oletter == c))
  1171. X                {
  1172. X                        *(o->ovar) = (o->odefault == 1) ? 0 : 1;
  1173. X                        goto next;
  1174. X                } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
  1175. X                {
  1176. X                        *(o->ovar) = (o->odefault == 2) ? 0 : 2;
  1177. X                        goto next;
  1178. X                } else if ((o->otype & NUMBER) && (o->oletter == c))
  1179. X                {
  1180. X                        *(o->ovar) = getnum(&s, c);
  1181. X                        goto next;
  1182. X                }
  1183. X        }
  1184. X
  1185. X        sprintf(message, "\"-%c\": invalid flag", c);
  1186. X        error(message);
  1187. X        quit();
  1188. X}
  1189. X
  1190. X/*
  1191. X * Translate a string into a number.
  1192. X * Like atoi(), but takes a pointer to a char *, and updates
  1193. X * the char * to point after the translated number.
  1194. X */
  1195. X#ifdef __STDC__
  1196. Xstatic int getnum (char **sp, int c)
  1197. X#else
  1198. X        static int
  1199. Xgetnum(sp, c)
  1200. X        char **sp;
  1201. X        int c;
  1202. X#endif
  1203. X{
  1204. X        register char *s;
  1205. X        register int n;
  1206. X        char message[80];
  1207. X
  1208. X        s = *sp;
  1209. X        if (*s < '0' || *s > '9')
  1210. X        {
  1211. X                if (c == '\0')
  1212. X                        return (-1);
  1213. X#ifdef AMIGA
  1214. X                sprintf(message,
  1215. X                    "number is required in option after '%c'", c);
  1216. X#else
  1217. X                sprintf(message, "number is required after -%c", c);
  1218. X#endif
  1219. X                error(message);
  1220. X                quit();
  1221. X        }
  1222. X
  1223. X        n = 0;
  1224. X        while (*s >= '0' && *s <= '9')
  1225. X                n = 10 * n + *s++ - '0';
  1226. X        *sp = s;
  1227. X        return (n);
  1228. X}
  1229. END_OF_FILE
  1230. if test 16082 -ne `wc -c <'Less1.4Z/src/option.c'`; then
  1231.     echo shar: \"'Less1.4Z/src/option.c'\" unpacked with wrong size!
  1232. fi
  1233. # end of 'Less1.4Z/src/option.c'
  1234. fi
  1235. if test -f 'Less1.4Z/src/output.c' -a "${1}" != "-c" ; then 
  1236.   echo shar: Will not clobber existing file \"'Less1.4Z/src/output.c'\"
  1237. else
  1238. echo shar: Extracting \"'Less1.4Z/src/output.c'\" \(8986 characters\)
  1239. sed "s/^X//" >'Less1.4Z/src/output.c' <<'END_OF_FILE'
  1240. X/*
  1241. X * High level routines dealing with the output to the screen.
  1242. X */
  1243. X
  1244. X#ifdef AMIGA
  1245. X/* Compile with -HPreHeader.q to get "less.h"! */
  1246. X#else
  1247. X#include "less.h"
  1248. X#endif
  1249. X
  1250. X
  1251. Xpublic int errmsgs;     /* Count of messages displayed by error() */
  1252. X
  1253. Xextern int sigs;
  1254. Xextern int sc_width, sc_height;
  1255. Xextern int ul_width, ue_width;
  1256. Xextern int so_width, se_width;
  1257. Xextern int bo_width, be_width;
  1258. X#ifdef AMIGA
  1259. Xextern int it_width, ie_width;
  1260. Xextern int nv_width, ne_width;
  1261. Xextern int nrow;  /* vertical screen size */
  1262. X#endif
  1263. X#ifdef EIGHTBIT
  1264. Xextern int bs_mode;
  1265. X#endif
  1266. Xextern int tabstop;
  1267. Xextern int twiddle;
  1268. Xextern int any_display;
  1269. Xextern char *line;
  1270. Xextern char *first_cmd;
  1271. X
  1272. X/*
  1273. X * Display the line which is in the line buffer.
  1274. X */
  1275. X#ifdef __STDC__
  1276. Xvoid put_line (void)
  1277. X#else
  1278. X        public void
  1279. Xput_line()
  1280. X#endif
  1281. X{
  1282. X#ifdef AMIGA
  1283. X        register unsigned char *p;
  1284. X#else
  1285. X        register char *p;
  1286. X#endif
  1287. X        register int c;
  1288. X        register int column;
  1289. X        extern int auto_wrap, ignaw;
  1290. X
  1291. X        if (sigs)
  1292. X                /*
  1293. X                 * Don't output if a signal is pending.
  1294. X                 */
  1295. X                return;
  1296. X
  1297. X        if (line == NULL)
  1298. X                line = (twiddle) ? "~" : "";
  1299. X
  1300. X        column = 0;
  1301. X#ifdef AMIGA
  1302. X        for (p = (unsigned char *)line;  *p != '\0';  p++)
  1303. X#else
  1304. X        for (p = line;  *p != '\0';  p++)
  1305. X#endif
  1306. X        {
  1307. X                switch (c = *p)
  1308. X                {
  1309. X                case UL_CHAR:
  1310. X                        ul_enter();
  1311. X                        column += ul_width;
  1312. X                        break;
  1313. X                case UE_CHAR:
  1314. X                        ul_exit();
  1315. X                        column += ue_width;
  1316. X                        break;
  1317. X                case BO_CHAR:
  1318. X                        bo_enter();
  1319. X                        column += bo_width;
  1320. X                        break;
  1321. X                case BE_CHAR:
  1322. X                        bo_exit();
  1323. X                        column += be_width;
  1324. X                        break;
  1325. X#ifdef AMIGA
  1326. X                case IT_CHAR:
  1327. X                        it_enter();
  1328. X                        column += it_width;
  1329. X                        break;
  1330. X                case IE_CHAR:
  1331. X                        it_exit();
  1332. X                        column += ie_width;
  1333. X                        break;
  1334. X                case NV_CHAR:
  1335. X                        nv_enter();
  1336. X                        column += nv_width;
  1337. X                        break;
  1338. X                case NE_CHAR:
  1339. X                        nv_exit();
  1340. X                        column += ne_width;
  1341. X                        break;
  1342. X#endif
  1343. X                case '\t':
  1344. X                        do
  1345. X                        {
  1346. X                                putchr(' ');
  1347. X                                column++;
  1348. X                        } while ((column % tabstop) != 0);
  1349. X                        break;
  1350. X                case '\b':
  1351. X#ifdef EIGHTBIT
  1352. X                        if (bs_mode == BS_CONTROL)
  1353. X                        {
  1354. X                                putchr('^');
  1355. X                                putchr(carat_char(c));
  1356. X                                column += 2;
  1357. X                                break;
  1358. X                        }
  1359. X#endif
  1360. X                        putbs();
  1361. X                        column--;
  1362. X                        break;
  1363. X                default:
  1364. X#ifdef EIGHTBIT
  1365. X                                /* Control characters are still control
  1366. X                                 * characters.  Replace them with some-
  1367. X                                 * thing printable.
  1368. X                                 */
  1369. X                        if (control_char(c))
  1370. X                        {
  1371. X                                putchr('^');
  1372. X                                putchr(carat_char(c));
  1373. X                                column += 2;
  1374. X                        }
  1375. X#else
  1376. X                        if (c & 0200)
  1377. X                        {
  1378. X                                /*
  1379. X                                 * Control characters arrive here as the
  1380. X                                 * normal character [carat_char(c)] with
  1381. X                                 * the 0200 bit set.  See pappend().
  1382. X                                 */
  1383. X                                putchr('^');
  1384. X                                putchr(c & 0177);
  1385. X                                column += 2;
  1386. X                        }
  1387. X#endif
  1388. X                        else
  1389. X                        {
  1390. X                                putchr(c);
  1391. X                                column++;
  1392. X                        }
  1393. X                }
  1394. X        }
  1395. X        if (column < sc_width || !auto_wrap || ignaw)
  1396. X                putchr('\n');
  1397. X}
  1398. X
  1399. X/*
  1400. X * Is a given character a "control" character?
  1401. X * {{ ASCII DEPENDENT }}
  1402. X */
  1403. X#ifdef __STDC__
  1404. Xint control_char (int c)
  1405. X#else
  1406. X        public int
  1407. Xcontrol_char(c)
  1408. X        int c;
  1409. X#endif
  1410. X{
  1411. X#ifdef EIGHTBIT
  1412. X        /* SAS says 0xff is a control character, for some reason */
  1413. X        return iscntrl(c) && c != 0xff;
  1414. X#else
  1415. X        return ( c < ' ' || c == '\177' );
  1416. X#endif
  1417. X}
  1418. X
  1419. X/*
  1420. X * Return the printable character used to identify a control character
  1421. X * (printed after a carat; e.g. '\3' => "^C").
  1422. X * {{ ASCII DEPENDENT }}
  1423. X */
  1424. X#ifdef __STDC__
  1425. Xint carat_char (int c)
  1426. X#else
  1427. X        public int
  1428. Xcarat_char(c)
  1429. X        int c;
  1430. X#endif
  1431. X{
  1432. X        return ((c == '\177') ? '?' : (c | 0100));
  1433. X}
  1434. X
  1435. X
  1436. Xstatic char obuf[1024];
  1437. Xstatic char *ob = obuf;
  1438. X
  1439. X/*
  1440. X * Flush buffered output.
  1441. X */
  1442. X#ifdef __STDC__
  1443. Xvoid flush (void)
  1444. X#else
  1445. X        public void
  1446. Xflush()
  1447. X#endif
  1448. X{
  1449. X#ifdef AMIGA
  1450. X        ttwrite ( obuf, (long) (ob-obuf));
  1451. X#else
  1452. X        write(1, obuf, ob-obuf);
  1453. X#endif
  1454. X        ob = obuf;
  1455. X}
  1456. X
  1457. X/*
  1458. X * Discard buffered output.
  1459. X */
  1460. X#ifdef __STDC__
  1461. Xvoid dropout (void)
  1462. X#else
  1463. X        public void
  1464. Xdropout()
  1465. X#endif
  1466. X{
  1467. X        ob = obuf;
  1468. X}
  1469. X
  1470. X/*
  1471. X * Output a character.
  1472. X */
  1473. X#ifdef __STDC__
  1474. Xvoid putchr (int c)
  1475. X#else
  1476. X        public void
  1477. Xputchr(c)
  1478. X        int c;
  1479. X#endif
  1480. X{
  1481. X        if (ob >= &obuf[sizeof(obuf)])
  1482. X                flush();
  1483. X        *ob++ = c;
  1484. X}
  1485. X
  1486. X/*
  1487. X * Output a string.
  1488. X */
  1489. X#ifdef __STDC__
  1490. Xvoid putstr (register char *s)
  1491. X#else
  1492. X        public void
  1493. Xputstr(s)
  1494. X        register char *s;
  1495. X#endif
  1496. X{
  1497. X        while (*s != '\0')
  1498. X                putchr(*s++);
  1499. X}
  1500. X
  1501. X/*
  1502. X * Output a message in the lower left corner of the screen
  1503. X * and wait for carriage return.
  1504. X */
  1505. X
  1506. Xstatic char return_to_continue[] = "  (press RETURN)";
  1507. X
  1508. X#ifdef __STDC__
  1509. Xvoid error (char *s)
  1510. X#else
  1511. X        public void
  1512. Xerror(s)
  1513. X        char *s;
  1514. X#endif
  1515. X{
  1516. X        register int c;
  1517. X        static char buf[2];
  1518. X
  1519. X        errmsgs++;
  1520. X#ifdef AMIGA
  1521. X        /* nrow tells us if the window has been opened yet.
  1522. X           any_display tells us if we have initialized reading a file yet.
  1523. X           If either of these are false, trying to write to the screen
  1524. X           now will cause trouble, either immediately or when we try to
  1525. X           regenerate a non-existant display.
  1526. X        */
  1527. X        if ( nrow < 2 || !any_display )
  1528. X#else
  1529. X        if (!any_display)
  1530. X#endif
  1531. X        {
  1532. X                /*
  1533. X                 * Nothing has been displayed yet.
  1534. X                 * Output this message on error output (file
  1535. X                 * descriptor 2) and don't wait for a keystroke
  1536. X                 * to continue.
  1537. X                 *
  1538. X                 * This has the desirable effect of producing all
  1539. X                 * error messages on error output if standard output
  1540. X                 * is directed to a file.  It also does the same if
  1541. X                 * we never produce any real output; for example, if
  1542. X                 * the input file(s) cannot be opened.  If we do
  1543. X                 * eventually produce output, code in edit() makes
  1544. X                 * sure these messages can be seen before they are
  1545. X                 * overwritten or scrolled away.
  1546. X                 */
  1547. X#ifdef AMIGA
  1548. X                /* If the window is too small, s may be NULL on Amiga */
  1549. X                if ( s )
  1550. X                    MyRequester( s );
  1551. X                else
  1552. X                    MyRequester ( "Error" );
  1553. X#else
  1554. X                write(2, s, strlen(s));
  1555. X                write(2, "\n", 1);
  1556. X#endif
  1557. X                return;
  1558. X        }
  1559. X
  1560. X        lower_left();
  1561. X        clear_eol();
  1562. X        so_enter();
  1563. X#ifdef AMIGA
  1564. X        if ( s )
  1565. X#endif
  1566. X        putstr(s);
  1567. X        putstr(return_to_continue);
  1568. X        so_exit();
  1569. X
  1570. X#if ONLY_RETURN
  1571. X        while ((c = getchr()) != '\n' && c != '\r')
  1572. X                bell();
  1573. X#else
  1574. X        c = getchr();
  1575. X        if (c != '\n' && c != '\r' && c != ' ')
  1576. X        {
  1577. X                buf[0] = c;
  1578. X                first_cmd = buf;
  1579. X        }
  1580. X#endif
  1581. X        lower_left();
  1582. X
  1583. X#ifdef AMIGA
  1584. X        if ( s &&
  1585. X                strlen(s) + sizeof(return_to_continue) +
  1586. X                so_width + se_width + 1 > sc_width
  1587. X                )
  1588. X#else
  1589. X        if (strlen(s) + sizeof(return_to_continue) +
  1590. X                so_width + se_width + 1 > sc_width)
  1591. X#endif
  1592. X                /*
  1593. X                 * Printing the message has probably scrolled the screen.
  1594. X                 * {{ Unless the terminal doesn't have auto margins,
  1595. X                 *    in which case we just hammered on the right margin. }}
  1596. X                 */
  1597. X                repaint();
  1598. X
  1599. X        flush();
  1600. X}
  1601. END_OF_FILE
  1602. if test 8986 -ne `wc -c <'Less1.4Z/src/output.c'`; then
  1603.     echo shar: \"'Less1.4Z/src/output.c'\" unpacked with wrong size!
  1604. fi
  1605. # end of 'Less1.4Z/src/output.c'
  1606. fi
  1607. if test -f 'Less1.4Z/src/version.c' -a "${1}" != "-c" ; then 
  1608.   echo shar: Will not clobber existing file \"'Less1.4Z/src/version.c'\"
  1609. else
  1610. echo shar: Extracting \"'Less1.4Z/src/version.c'\" \(8918 characters\)
  1611. sed "s/^X//" >'Less1.4Z/src/version.c' <<'END_OF_FILE'
  1612. X#ifdef AMIGA
  1613. X/* Compile with -HPreHeader.q to get "less.h"! */
  1614. X#else
  1615. X#include "less.h"
  1616. X#endif
  1617. X
  1618. X/*
  1619. X *              less
  1620. X *      Copyright (c) 1984,1985  Mark Nudelman
  1621. X *
  1622. X *      This program may be freely used and/or modified,
  1623. X *      with the following provisions:
  1624. X *      1. This notice and the above copyright notice must remain intact.
  1625. X *      2. Neither this program, nor any modification of it,
  1626. X *         may be sold for profit without written consent of the author.
  1627. X *
  1628. X *      -----------------------------------------------------------------
  1629. X *
  1630. X *      This program is a paginator similar to "more",
  1631. X *      but allows you to move both forward and backward in the file.
  1632. X *      Commands are based on "more" and "vi".
  1633. X *
  1634. X *      ----------------------- CHANGES ---------------------------------
  1635. X *
  1636. X *          Allowed use on standard input               1/29/84   markn
  1637. X *          Added E, N, P commands                      2/1/84    markn
  1638. X *          Added '=' command, 'stop' signal handling   4/17/84   markn
  1639. X *          Added line folding                          4/20/84   markn
  1640. X *      v2: Fixed '=' command to use BOTTOM_PLUS_ONE,
  1641. X *          instead of TOP, added 'p' & 'v' commands    4/27/84   markn
  1642. X *      v3: Added -m and -t options, '-' command        5/3/84    markn
  1643. X *      v4: Added LESS environment variable             5/3/84    markn
  1644. X *      v5: New comments, fixed '-' command slightly    5/3/84    markn
  1645. X *      v6: Added -Q, visual bell                       5/15/84   markn
  1646. X *      v7: Fixed jump_back(n) bug: n should count real
  1647. X *          lines, not folded lines.  Also allow number
  1648. X *          on G command.                               5/24/84   markn
  1649. X *      v8: Re-do -q and -Q commands                    5/30/84   markn
  1650. X *      v9: Added "+<cmd>" argument                     9/25/84   markn
  1651. X *      v10: Fixed bug in -b<n> argument processing     10/10/84  markn
  1652. X *      v11: Made error() ring bell if \n not entered.  10/18/84  markn
  1653. X *      -----------------------------------------------------------------
  1654. X *      v12: Reorganized signal handling and made
  1655. X *           portable to 4.2bsd.                        2/13/85   mark
  1656. X *      v13: Reword error message for '-' command.      2/16/85   mark
  1657. X *      v14: Added -bf and -bp variants of -b.          2/22/85   mark
  1658. X *      v15: Miscellaneous changes.                     2/25/85   mark
  1659. X *      v16: Added -u flag for backspace processing.    3/13/85   mark
  1660. X *      v17: Added j and k commands,
  1661. X *              changed -t default.                     4/13/85   mark
  1662. X *      v18: Rewrote signal handling code.              4/20/85   mark
  1663. X *      v19: Got rid of "verbose" eq_message().         5/2/85    mark
  1664. X *           Made search() scroll in some cases.
  1665. X *      v20: Fixed screen.c ioctls for System V.        5/21/85   mark
  1666. X *      v21: Fixed some first_cmd bugs.                 5/23/85   mark
  1667. X *      v22: Added support for no RECOMP nor REGCMP.    5/24/85   mark
  1668. X *      v23: Miscellanous changes and prettying up.     5/25/85   mark
  1669. X *              Posted to USENET.
  1670. X *      v24: Added ti,te terminal init & de-init       6/3/85 Mike Kersenbrock
  1671. X *      v25: Added -U flag, standout mode underlining.  6/8/85    mark
  1672. X *      v26: Added -M flag.                             6/9/85    mark
  1673. X *           Use underline termcap (us) if it exists.
  1674. X *      v27: Renamed some variables to make unique in   6/15/85   mark
  1675. X *           6 chars.  Minor fix to -m.
  1676. X *      v28: Fixed right margin bug.                    6/28/85   mark
  1677. X *      v29: Incorporated M.Rose's changes to signal.c  6/28/85   mark
  1678. X *      v30: Fixed stupid bug in argument processing.   6/29/85   mark
  1679. X *      v31: Added -p flag, changed repaint algorithm.  7/15/85   mark
  1680. X *           Added kludge for magic cookie terminals.
  1681. X *      v32: Added cat_file if output not a tty.        7/16/85   mark
  1682. X *      v33: Added -e flag and EDITOR.                  7/23/85   mark
  1683. X *      v34: Added -s flag.                             7/26/85   mark
  1684. X *      v35: Rewrote option handling; added option.c.   7/27/85   mark
  1685. X *      v36: Fixed -e flag to work if not last file.    7/29/85   mark
  1686. X *      v37: Added -x flag.                             8/10/85   mark
  1687. X *      v38: Changed prompting; created prompt.c.       8/19/85   mark
  1688. X *      v39: (Not -p) does not initially clear screen.  8/24/85   mark
  1689. X *      v40: Added "skipping" indicator in forw().      8/26/85   mark
  1690. X *              Posted to USENET.
  1691. X *      v41: ONLY_RETURN, control char commands,        9/17/85   mark
  1692. X *           faster search, other minor fixes.
  1693. X *      v42: Added ++ command line syntax;              9/25/85   mark
  1694. X *           ch_fsize for pipes.
  1695. X *      v43: Added -h flag, changed prim.c algorithms.  10/15/85  mark
  1696. X *      v44: Made END print in all cases of eof;        10/16/85  mark
  1697. X *           ignore SIGTTOU after receiving SIGTSTP.
  1698. X *      v45: Never print backspaces unless -u.          10/16/85  mark
  1699. X *      v46: Backwards scroll in jump_loc.              10/24/85  mark
  1700. X *      v47: Fixed bug in edit(): *first_cmd==0         10/30/85  mark
  1701. X *      v48: Use TIOCSETN instead of TIOCSETP.          11/16/85  mark
  1702. X *           Added marks (m and ' commands).
  1703. X *              Posted to USENET.
  1704. X *      -----------------------------------------------------------------
  1705. X *      v49: Fixed bug: signal didn't clear mcc.        1/9/86    mark
  1706. X *      v50: Added ' (quote) to gomark.                 1/15/86   mark
  1707. X *      v51: Added + cmd, fixed problem if first_cmd
  1708. X *           fails, made g cmd sort of "work" on pipes
  1709. X *           even if bof is no longer buffered.         1/16/86   mark
  1710. X *      v52: Made short files work better.              1/17/86   mark
  1711. X *      v53: Added -P option.                           1/20/86   mark
  1712. X *      v54: Changed help to use HELPFILE.              1/20/86   mark
  1713. X *      v55: Messages work better if not tty output.    1/23/86   mark
  1714. X *      v56: Added -l option.                           1/24/86   mark
  1715. X *      v57: Fixed -l to get confirmation before
  1716. X *           overwriting an existing file.              1/31/86   mark
  1717. X *      v58: Added filename globbing.                   8/28/86   mark
  1718. X *      v59: Fixed some bugs with very long filenames.  9/15/86   mark
  1719. X *      v60: Incorporated changes from Leith (Casey)
  1720. X *           Leedom for boldface and -z option.         9/26/86   mark
  1721. X *      v61: Got rid of annoying repaints after ! cmd.  9/26/86   mark
  1722. X *              Posted to USENET.
  1723. X *      -----------------------------------------------------------------
  1724. X *      v62: Added is_directory(); change -z default to
  1725. X *           -1 instead of 24; cat-and-exit if -e and
  1726. X *           file is less than a screenful.             12/23/86  mark
  1727. X *      v63: Fixed bug in cat-and-exit if > 1 file.     1/8/87    mark
  1728. X *      v64: Changed puts/putstr, putc/putchr,
  1729. X *           getc/getchr to avoid name conflict with
  1730. X *           stdio functions.                           1/12/87  mark
  1731. X *      v65: Allowed '-' command to change NUMBER
  1732. X *           valued options (thanks to Gary Puckering)  1/26/87  mark
  1733. X *      v66: Fixed bug: prepaint should use force=1.    2/13/87  mark
  1734. X *      v67: Added !! and % expansion to ! command.     2/24/87  mark
  1735. X *      v68: Added SIGWINCH and TIOCGWINSZ support;
  1736. X *           changed is_directory to bad_file.
  1737. X *           (thanks to J. Robert Ward)                 2/25/87  mark
  1738. X *      v69: Added SIGWIND and WIOCGETD (for Unix PC).  2/25/87  mark
  1739. X *      v70: Changed help cmd from 'h' to 'H'; better
  1740. X *           error msgs in bad_file, errno_message.     3/13/87  mark
  1741. X *      v71: Changed -p to -c, made triple -c/-C
  1742. X *           for clear-eol like more's -c.              5/11/87  mark
  1743. X *      v72: Added -E, -L, use $SHELL in lsystem().     6/26/87  mark
  1744. X *           (thanks to Steve Spearman)
  1745. X *      v73: Allow Examine "#" for previous file.       6/26/87  mark
  1746. X *              Posted to USENET 8/25/87.
  1747. X *      -----------------------------------------------------------------
  1748. X *      Amiga ports:
  1749. X *      (Any history previous to 1.3 lost)
  1750. X *      1.3: Original? port to Amiga by Bob Leivian     ???
  1751. X *      1.3Z: Bugs fixed to run under AmigaDos 1.3 and  6/01/91  rlz
  1752. X *           2.0 on all Amiga models through A3000.
  1753. X *           Determines size of full screen workbench
  1754. X *           window, and handles whatever size it gets
  1755. X *           and whatever font.  Permits window resizing,
  1756. X *           close gadget.  Recognizes Amiga ANSI
  1757. X *           graphic rendition codes.
  1758. X *      1.4Z: Several bugs fixed.  Error handling       6/08/91  rlz
  1759. X *           much improved.  Made residentable.
  1760. X *           User-specifiable window size/placement.
  1761. X *           Recognizes international character set
  1762. X *           characters 160 - 255 (decimal).  Regular
  1763. X *           expression searches added.
  1764. X */
  1765. X
  1766. Xchar version[] =
  1767. X"@(#)Amiga Less 1.4Z (ported from Unix version 73)";
  1768. END_OF_FILE
  1769. if test 8918 -ne `wc -c <'Less1.4Z/src/version.c'`; then
  1770.     echo shar: \"'Less1.4Z/src/version.c'\" unpacked with wrong size!
  1771. fi
  1772. # end of 'Less1.4Z/src/version.c'
  1773. fi
  1774. echo shar: End of archive 2 \(of 7\).
  1775. cp /dev/null ark2isdone
  1776. MISSING=""
  1777. for I in 1 2 3 4 5 6 7 ; do
  1778.     if test ! -f ark${I}isdone ; then
  1779.     MISSING="${MISSING} ${I}"
  1780.     fi
  1781. done
  1782. if test "${MISSING}" = "" ; then
  1783.     echo You have unpacked all 7 archives.
  1784.     rm -f ark[1-9]isdone
  1785. else
  1786.     echo You still need to unpack the following archives:
  1787.     echo "        " ${MISSING}
  1788. fi
  1789. ##  End of shell archive.
  1790. exit 0
  1791. -- 
  1792. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  1793. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  1794. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  1795.